//  
//  Sprawdzacz
//  
//  Author:
//       Grzegorz Żur <grzegorz.zur@gmail.com>
// 
//  Copyright (c) 2010-2011 Grzegorz Żur
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

using System;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;

namespace Sprawdzacz
{

	public class KW : Validator
	{

		public const string NAME = "Księga wieczysta";

		private const string LIST = "KW.txt";
		
		private static readonly Regex PATTERN = new Regex ("^[a-zA-Z0-9]{4}[0-9]{9}$");

		private const int BASE = 1;

		private const int DIVIDER = 10;

		private const int CHECKSUM_POSITION = 12;

		private static readonly char[] LETTERS = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'W', 'Y', 'Z' };

		private static readonly int[] WEIGHTS = { 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 0 };

		private Dictionary dictionary;

		public KW () : base(NAME)
		{
			Assembly assembly = Assembly.GetExecutingAssembly ();
			Stream stream = assembly.GetManifestResourceStream (typeof(KW), LIST);
			dictionary = new Dictionary (stream);
		}

		public override Validation Validate (string number)
		{
			number = Normalize (number);
			if (!PATTERN.IsMatch (number))
				return new Validation (false, Name, number, null);
			
			int[] digits = Numbers (number);
			int checksum = digits[CHECKSUM_POSITION];
			int sum = Sum (WEIGHTS, digits);
			int reminder = sum % DIVIDER;
			if (reminder != checksum)
				return new Validation (false, Name, number, null);
			
			string location = number.Substring (0, 4);
			string sequence = number.Substring (4, 8);
			int seq = int.Parse(sequence);
			if (seq == 0)
				return new Validation (false, Name, number, null);
			
			string check = number.Substring (12, 1);
			if (!dictionary.Exists (location))
				return new Validation (false, Name, number, null);
			
			string city = dictionary.Decode (location);
			string message = string.Format ("{0}/{1}/{2} {3}", location, sequence, check, city);
			return new Validation (true, Name, number, message);
		}

		public override int Number (char c)
		{
			if (char.IsLetter (c))
				return Array.IndexOf (LETTERS, char.ToUpper (c)) + BASE;
			else
				return base.Number (c);
		}
		
	}
	
}
